package org.example.argument;

import lombok.extern.slf4j.Slf4j;
import org.example.anno.User;
import org.example.model.LoginUser;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.lang.reflect.Parameter;
/**
 * WebAgrumentResolve 类实现 HandlerMethodArgumentResolver 接口，
 * 用于自定义方法参数解析器，将请求中的数据绑定到方法参数上
 *
 * // 选哟在webconfig中配置吗？
 *
 *
 *
 *
 */
@Component
@Slf4j
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {


    /**
     * 判断当前参数是否需要此解析器进行处理
     * @param methodParameter 方法参数对象，包含方法参数的所有信息
     * @return 如果参数类型为LoginUser并且带有@User注解则返回true，否则返回false
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        Parameter parameter = methodParameter.getParameter();
        //判断参数类型是否为LoginUser，并且是否有@User注解
        return  parameter.getType() == LoginUser.class && parameter.isAnnotationPresent(User.class);
    }

    /**
     * 实际参数解析方法，从请求中获取数据并转换为方法参数所需的对象
     * @param methodParameter 方法参数对象
     * @param modelAndViewContainer ModelAndView容器，用于存储模型和视图信息
     * @param nativeWebRequest 原生请求对象，可以访问请求属性
     * @param webDataBinderFactory Web数据绑定工厂，用于创建数据绑定器
     * @return 解析后的参数对象，即LoginUser实例
     * @throws Exception 可能抛出的异常
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        //从request的attr "loginUser" 中将数据取出 并注入参数
        LoginUser loginUser = (LoginUser) nativeWebRequest.getAttribute("loginUser", NativeWebRequest.SCOPE_REQUEST);
        log.info("loginUser:{}",loginUser);
        return loginUser;
    }
}
